package mastermind.game;

import java.util.HashMap;
import java.util.Map;

import mastermind.net.Protocol;

/**
 * An instance of a MM game, recording player guesses. Should only be used on
 * server side.
 */
public class Game {
	private Pieces secret;
	private Map<Pieces, String> guesses;

	public Game() {
		this(Pieces.randomPieces(Protocol.pieceColours,
				Protocol.SECRET_DEFAULT_LENGTH));
	}

	public Game(Pieces secret) {
		guesses = new HashMap<Pieces, String>();
		this.secret = secret;
	}

	/**
	 * @return True if player has guesses remaining, i.e. game not over
	 */
	public boolean haveGuesses() {
		return guesses.size() < Protocol.NUM_GUESSES;
	}

	/**
	 * Guesses given pieces and compares to secret, returning feedback
	 * 
	 * @param p
	 *            Guessed pieces
	 * @return Feedback String of w & b
	 * @throws GameException
	 */
	public String makeGuess(Pieces p) throws GameException {
		if (!haveGuesses())
			throw new GameException("out of guesses, game over");

		String f = secret.feedback(p);
		guesses.put(p, f);
		return f;
	}

	public Map<Pieces, String> getGuesses() {
		return guesses;
	}
	
	public Pieces getSecret() {
		return secret;
	}
	
	/**
	 * @return Score object for this game
	 */
	public Score getScore() {
		int score = (haveGuesses()) ? Protocol.NUM_GUESSES - guesses.size() + 1
				: -5;
		return new Score(score);
	}

	/**
	 * Returns whether the given feedback indicates a match with the secret, i.e
	 * an all 'b' string
	 */
	public static boolean correctGuess(String feedback) {
		return feedback.length() == Protocol.SECRET_DEFAULT_LENGTH
				&& !feedback.contains("w");
	}

}
